package com.hdax.dm.service;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.hdax.dm.common.exception.DmException;
import com.hdax.dm.common.exception.user.UserLoginException;
import com.hdax.dm.dto.user.TokenDto;
import com.hdax.dm.dto.user.UserDto;
import com.hdax.dm.dto.user.UserTokenDto;
import com.hdax.dm.entity.base.Image;
import com.hdax.dm.entity.user.User;
import com.hdax.dm.feign.base.ImageFeign;
import com.hdax.dm.feign.user.UserFeign;
import com.hdax.dm.vo.UserVo;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class UserLoginService {

    @Autowired
    private UserFeign userFeign;
    @Autowired
    private ImageFeign imageFeign;
    @Autowired      //向redis中存值
    private RedisTemplate<String,String> redisTemplate;
    @Autowired      //消息队列
    private RabbitTemplate rabbitTemplate;

    //注册账号发送验证码
    public void code(String phone){
        String rcode = redisTemplate.opsForValue().get("vcode"+phone);
        User user = userFeign.find(phone);
        if (rcode != null && !rcode.equals("")){
            throw new UserLoginException(UserLoginException.ERR_INFO.FAIL_VCODE_MSG,
                    UserLoginException.ERR_INFO.FAIL_VCODE_CODE);
        }
        if (user != null){
            throw new UserLoginException(UserLoginException.ERR_INFO.YES_PHONE_MSG,
                    UserLoginException.ERR_INFO.YES_PHONE_CODE);
        }
        //发送验证码
        int min = 1000;
        int max = 9999;
        Random random = new Random();
        int i = random.nextInt(max);
        while (i < min){
            i = i + min;
        }
        //发送短信验证码，往redis中存值
        redisTemplate.opsForValue().set("vcode"+phone,i+"",60L,TimeUnit.SECONDS);
        Map<String,String> map = new HashMap<>();
        map.put("vcode",rcode);
        map.put("phoneNumber",phone);
        //--------------------------------------往哪个发，内容
        rabbitTemplate.convertAndSend("dmsms",map);
    }

    //注册账号
    public boolean register(Map<String,String> map){
        String rcode = redisTemplate.opsForValue().get("vcode"+map.get("phone"));
        if (rcode == null || rcode.equals("")){
            throw new UserLoginException(UserLoginException.ERR_INFO.NO_VCODE_MSG,
                    UserLoginException.ERR_INFO.NO_VCODE_CODE);
        }
        if (!rcode.equals(map.get("vcode"))){
            throw new UserLoginException(UserLoginException.ERR_INFO.ERR_VCODE_MSG,
                    UserLoginException.ERR_INFO.ERR_VCODE_CODE);
        }
        boolean b = userFeign.register(map.get("phone"), map.get("password"));
        redisTemplate.delete("vcode"+map.get("phone"));
        return b;
    }


    //账号密码登录
    public TokenDto login(UserVo userVo,String userAgent) throws DmException {
        User user = userFeign.find(userVo.getPhone());
        if(user == null){
            throw new UserLoginException(UserLoginException.ERR_INFO.NO_USER_MSG,
                    UserLoginException.ERR_INFO.NO_USER_CODE);
        }
        if (!user.getPassword().equals(SecureUtil.md5(userVo.getPassword()))){
            throw new UserLoginException(UserLoginException.ERR_INFO.ERR_PWD_MSG,
                    UserLoginException.ERR_INFO.ERR_PWD_CODE);
        }
        TokenDto tokenDto = new TokenDto();
        StringBuilder builder = new StringBuilder();
        Long genTime = System.currentTimeMillis();  //系统时间
        builder.append("PC:");
        builder.append(user.getId()+"-");
        builder.append(user.getNickName()+"-");
        builder.append(genTime+"-");
        builder.append(SecureUtil.md5(userAgent).substring(12));
        tokenDto.setToken(builder.toString());
        tokenDto.setGenTime(genTime);
        tokenDto.setExtTime(genTime+2*60*60*1000L);
        tokenDto.setUserId(user.getId());
        //将token存储到redis
        redisTemplate.opsForValue().set("token:"+builder.toString(),JSON.toJSONString(tokenDto),2L,TimeUnit.HOURS);
//        redisTemplate.opsForValue().set("userId",user.getId()+"",2L,TimeUnit.HOURS);
        BeanUtils.copyProperties(user,tokenDto);
        return tokenDto;
    }

    /*短信登陆发送验证码*/
    public void msg(String phone) throws DmException{
        String vcode = redisTemplate.opsForValue().get("vcode:"+phone);
        if (vcode != null){
            throw new UserLoginException(UserLoginException.ERR_INFO.FAIL_VCODE_MSG,
                    UserLoginException.ERR_INFO.FAIL_VCODE_CODE);
        }
        if (phone == null || phone.trim().equals("")) {
            throw new UserLoginException(UserLoginException.ERR_INFO.NULL_PHONE_MSG,
                    UserLoginException.ERR_INFO.NULL_PHONE_CODE);
        }
        if (phone.length() != 11){
            throw new UserLoginException(UserLoginException.ERR_INFO.ERROR_PHONE_MSG,
                    UserLoginException.ERR_INFO.ERROR_PHONE_CODE);
        }
        //发送验证码
        int min = 1000;
        int max = 9999;
        Random random = new Random();
        int i = random.nextInt(max);
        while (i < min){
            i = i + min;
        }
        //发送短信手机号,往redis中存值
        redisTemplate.opsForValue().set("vcode:"+phone,i+"",60L, TimeUnit.SECONDS);
        Map<String,String> messages = new HashMap<>();
        messages.put("vcode",i+"");
        messages.put("phoneNumber",phone);
        //--------------------------------------向哪个发，发送的数据
        rabbitTemplate.convertAndSend("dmsms",messages);
    }

    /*验证码登录*/                                                //本机唯一标识
    public TokenDto msgLogin(String inputCode,String phone,String userAgent){
        User user = userFeign.find(phone);
        String vcode = redisTemplate.opsForValue().get("vcode:"+phone);

        if (user == null){
            throw new UserLoginException(UserLoginException.ERR_INFO.NO_USER_MSG,
                    UserLoginException.ERR_INFO.NO_USER_MSG);
        }
        if (inputCode == null || inputCode.trim().equals("")){
            throw new UserLoginException(UserLoginException.ERR_INFO.NULL_VCODE_MSG,
                    UserLoginException.ERR_INFO.NULL_VCODE_CODE);
        }
        if (vcode == null || vcode.equals("")){
            throw new UserLoginException(UserLoginException.ERR_INFO.NO_VCODE_MSG,
                    UserLoginException.ERR_INFO.NO_VCODE_CODE);
        }
        if (!vcode.equals(inputCode)){
            throw new UserLoginException(UserLoginException.ERR_INFO.ERR_VCODE_MSG,
                    UserLoginException.ERR_INFO.ERR_VCODE_CODE);
        }
        TokenDto tokenDto = new TokenDto();
        Long genTime  = System.currentTimeMillis();
        StringBuilder builder = new StringBuilder();
        builder.append("PC:");
        builder.append(user.getId()+"-");
        builder.append(user.getNickName()+"-");
        builder.append(genTime+"-");
        builder.append(SecureUtil.md5(userAgent).substring(12));
        tokenDto.setToken(builder.toString());
        tokenDto.setGenTime(genTime);
        tokenDto.setExtTime(genTime+2*60*60*1000L);
        tokenDto.setUserId(user.getId());
        //将token存储redis
        redisTemplate.opsForValue().set("token:"+builder.toString(), JSON.toJSONString(tokenDto),2L,TimeUnit.HOURS);
        BeanUtils.copyProperties(user,tokenDto);
        redisTemplate.delete("vcode:"+phone);
        return tokenDto;

    }

}
